package com.example.boardroom.demo;

import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import com.alibaba.fastjson.JSON;
import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.TimeUtils;
import com.example.boardroom.R;
import com.example.boardroom.appusagestatistics.AppUsageStatisticsFragment;
import com.example.boardroom.demo.room.AppDatabase;
import com.example.boardroom.demo.room.TimesDao;
import com.example.boardroom.demo.room.TimesTable;
import com.example.boardroom.demo.times.BeanTimes;
import com.example.boardroom.demo.times.TimesActivity;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.callback.StringCallback;
import com.lzy.okgo.model.Response;

import org.json.JSONArray;

import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Logger;
/*
    Android 8.0 系统不允许后台应用创建后台服务，故只能使用Context.startForegroundService()启动服务
    创建服务后，应用必须在5秒内调用该服务的 startForeground() 显示一条可见通知，
    声明有服务在挂着，不然系统会停止服务 + ANR 套餐送上。
    Notification 要加 Channel，系统的要求
    为什么要在onStart里再次调用startForeground()？
    答：这一条主要是针对后台保活的服务，如果在服务A运行期间，保活机制又startForegroundService启动了一次服务A，
    那么这样不会调用服务A的onCreate方法，只会调用onStart方法。如果不在onStart方法里再挂个通知的话，
    系统会认为你使用了 startForegroundService 却不在 5 秒内给通知，很傻地就停止服务 + ANR 套餐送
*/

public class HelloService extends Service {

    private static final String TAG = "hello_lufei";
    public static final String CHANNEL_ID_STRING = "service_01";
    private Notification notification;
    String startupTime, startupTime2;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        Log.i(TAG, "onCreate: ...服务创建...");
        cal = Calendar.getInstance();
        cal.add(Calendar.YEAR, -1);
        mUsageStatsManager = (UsageStatsManager) this
                .getSystemService(Context.USAGE_STATS_SERVICE); //Context.USAGE_STATS_SERVICE
        initDB();
    }

    public static String getSystemStartupTime() {
        long time = System.currentTimeMillis() - SystemClock.elapsedRealtime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d1 = new Date(time);
        return format.format(d1);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand: start....服务启动...");
        startupTime = TimeUtils.millis2String(System.currentTimeMillis() - SystemClock.elapsedRealtime());
        startupTime2 = TimeUtils.getNowString();


        Toast.makeText(this, "服务启动", Toast.LENGTH_SHORT).show();
        //下面是判断 Android8.0 以后的服务,设置为后台服务的操作
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationChannel mChannel = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            mChannel = new NotificationChannel(CHANNEL_ID_STRING,
                    getString(R.string.app_name),
                    NotificationManager.IMPORTANCE_LOW);
            manager.createNotificationChannel(mChannel);
            notification = new Notification.Builder(getApplicationContext(), CHANNEL_ID_STRING).build();
            //注意 startForeground(1, notification);中不能为0，不然会出现如下问题
            //Context.startForegroundService() did not then call Service.startForeground()
            startForeground(1, notification);
        }


        startTime();


        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        stopTime();
    }

    private Timer timer = null;//计时器
    private TimerTask task = null;


    //启动
    private void startTime() {
        timer = new Timer();
        task = new TimerTask() {
            @Override
            public void run() {
                Log.i("lufei", "此处自己设置");
                try {
                    //此处自己设置

                    getTimes();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        };
        //1000ms执行一次
//        timer.schedule(task, 1000, 2000);
    }

    //关闭
    private void stopTime() {
        if (timer != null)
            timer.cancel();
        timer = null;//据说这样不会自动跳出软件
    }

    UsageStatsManager mUsageStatsManager;
    Calendar cal;

    private long bootTime() {
        return System.currentTimeMillis() - SystemClock.elapsedRealtimeNanos() / 1000000;
    }

    private void getdata() {
        TimesTable timesTable = new TimesTable();
        timesTable.startupTime = TimeUtils.millis2String(bootTime());
        timesTable.currentTime = TimeUtils.getNowString();
        timesDao.insertAll(timesTable);

        cal.add(Calendar.DAY_OF_YEAR, -1);

        List<UsageStats> queryUsageStats = mUsageStatsManager
                .queryUsageStats(UsageStatsManager.INTERVAL_DAILY, cal.getTimeInMillis(),
                        System.currentTimeMillis());

        List<UsageStats> queryUsageStats2 = new ArrayList<>();
        for (UsageStats usageStat : queryUsageStats) {


            if (usageStat.getLastTimeStamp() > cal.getTimeInMillis()) {
                queryUsageStats2.add(usageStat);

            }
        }


//        upLoadData2(queryUsageStats2);


        Log.i("lufei", "收集到数据:" + queryUsageStats.get(0).getPackageName());
    }

    private byte[] getIcon(UsageStats usageStats) {
        byte[] bitmapdata = new byte[0];
        try {
            Drawable icon = getApplicationContext().getPackageManager()
                    .getApplicationIcon(usageStats.getPackageName());

            Bitmap bitmap = ((BitmapDrawable) icon).getBitmap();
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
            bitmapdata = stream.toByteArray();
        } catch (PackageManager.NameNotFoundException e) {
            Log.w("lufei", "NameNotFoundException");
        }
        return bitmapdata;
    }

    private void upLoadData2(List<UsageStats> list) {
        List<HashMap> list1 = new ArrayList<>();
        for (UsageStats usageStats : list) {
            HashMap<String, String> hashMap = new HashMap<>();
            hashMap.put("packageName", usageStats.getPackageName());
            hashMap.put("firstTimeStamp", String.valueOf(usageStats.getFirstTimeStamp()));
            hashMap.put("lastTimeStamp", String.valueOf(usageStats.getLastTimeStamp()));
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                hashMap.put("lastTimeVisible", String.valueOf(usageStats.getLastTimeVisible()));
            } else {
                hashMap.put("lastTimeVisible", String.valueOf(usageStats.getLastTimeStamp()));
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                hashMap.put("totalTimeVisible", String.valueOf(usageStats.getTotalTimeVisible()));
            } else {
                hashMap.put("totalTimeVisible", "1000");
//                hashMap.put("totalTimeVisible", String.valueOf(getIcon(usageStats)));
            }
            hashMap.put("startupTime", startupTime);
            hashMap.put("imageByte", startupTime2);
            list1.add(hashMap);
        }
        String jsonString2 = JSON.toJSONString(list1);

        LogUtils.i("lufeia", jsonString2);
        OkGo.<String>post("http://192.168.1.206:19301/screen/recordUsedTime")
                .tag(this)
                .upJson(jsonString2)
                .execute(new StringCallback() {
                    @Override
                    public void onSuccess(Response<String> response) {


                        LogUtils.i("lufei", "onSuccess", response.body(), response.message(), response.code());
                    }

                    @Override
                    public void onError(Response<String> response) {
                        super.onError(response);
                        LogUtils.i("lufei", "onError");
                    }

                    @Override
                    public void onFinish() {
                        LogUtils.i("lufei", "onFinish");
                        super.onFinish();
                    }
                });

    }

    private TimesDao timesDao;

    private void initDB() {
        timesDao = AppDatabase.getInstance(this).userDao();
    }

    private List<BeanTimes> data;

    private void getTimes() {
        data = new ArrayList<>();
//        LogUtils.i("lufei_time",   "包名: "+usageStats.getPackageName() ,"开始时间: "+ TimeUtils.millis2String(usageStats.getFirstTimeStamp()) +"-----  结束时间: "+TimeUtils.millis2String(usageStats.getLastTimeStamp()),"启动次数: "+"1");
        String startupTime = TimeUtils.millis2String(System.currentTimeMillis() - SystemClock.elapsedRealtime());
        long startupTime_long = System.currentTimeMillis() - SystemClock.elapsedRealtime();
        mUsageStatsManager = (UsageStatsManager) this
                .getSystemService(Context.USAGE_STATS_SERVICE); //Context.USAGE_STATS_SERVICE
        List<UsageStats> usageStatss = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, System.currentTimeMillis() - SystemClock.elapsedRealtime(), TimeUtils.getNowMills());
        Collections.sort(usageStatss, new LastTimeLaunchedComparatorDesc());
        for (UsageStats usageStats : usageStatss) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                LogUtils.i("lufei_time", "包名:" + usageStats.getPackageName(), "开始时间: " + TimeUtils.millis2String(usageStats.getFirstTimeStamp()) + "-----  结束时间: " + TimeUtils.millis2String(usageStats.getLastTimeStamp()), "启动次数: " + "1"
                        , "运行总时长 : " + usageStats.getTotalTimeVisible() / 1000 / 60 + "分钟", "开机时间:" + TimeUtils.millis2String(System.currentTimeMillis() - SystemClock.elapsedRealtime()), "从开机开始算，累计运行时间:" + (usageStats.getLastTimeStamp() - usageStats.getFirstTimeStamp()) / 1000 / 60 + "分钟"
                        , "反向计算出启动时间: " + TimeUtils.millis2String((usageStats.getLastTimeStamp() - usageStats.getTotalTimeVisible())) + "---- 结束时间: " + TimeUtils.millis2String(usageStats.getLastTimeStamp())
                        , "getTotalTimeInForeground: " + usageStats.getTotalTimeInForeground()
                        , "getTotalTimeVisible: " + usageStats.getTotalTimeVisible()
                        , "getTotalTimeForegroundServiceUsed: " + usageStats.getTotalTimeForegroundServiceUsed());
                if (usageStats.getTotalTimeVisible() > 0) {
                    data.add(new BeanTimes(usageStats, ""));

                }
            }
        }
        xxx(data);

    }

    private class LastTimeLaunchedComparatorDesc implements Comparator<UsageStats> {

        @Override
        public int compare(UsageStats left, UsageStats right) {
            return Long.compare(right.getLastTimeUsed(), left.getLastTimeUsed());
        }
    }

    private void xxx(List<BeanTimes> data) {
        List<Object> list = new ArrayList<>();
        HashMap<String, Object> hashMap;
        for (BeanTimes datum : data) {
            hashMap = new HashMap<>();
            hashMap.put("deviceId", 1);
            hashMap.put("handleType", "1");
            hashMap.put("packageName", datum.usageStats.getPackageName());
            hashMap.put("handleStatus", AppUtils.isAppRunning(datum.usageStats.getPackageName()) ? "0" : "1");
            hashMap.put("appName", AppUtils.getAppName(datum.usageStats.getPackageName()));
            LogUtils.i("lufei_xxx", datum.usageStats.getPackageName(), AppUtils.isAppForeground(datum.usageStats.getPackageName()) ? "0" : "1", AppUtils.getAppName(datum.usageStats.getPackageName())
                    , "======================"
                    , isProcessRunning(this, getPackageUid(this, datum.usageStats.getPackageName()))
            );
            list.add(hashMap);
        }
        String s = GsonUtils.toJson(list);
        LogUtils.i("lufei_bbb", s);
        upLoadAppStatus(s);
    }

    private void upLoadAppStatus(String json) {

        OkGo.<String>post("http://192.168.1.26:19100/link/deviceUseLog/batchAddDeviceUseLog")
                .tag(this)
                .upJson(json)
                .execute(new StringCallback() {
                    @Override
                    public void onSuccess(Response<String> response) {

                    }
                });
    }


    //获取已安装应用的 uid，-1 表示未安装此应用或程序异常
    public static int getPackageUid(Context context, String packageName) {
        try {
            ApplicationInfo applicatiOnInfo = context.getPackageManager().getApplicationInfo(packageName, 0);
            if (applicatiOnInfo != null) {
                LogUtils.i("lufei_uid", applicatiOnInfo.uid);
                return applicatiOnInfo.uid;
            }
        } catch (Exception e) {
            return -1;
        }
        return -1;
    }

    /**
     * 判断某一 uid 的程序是否有正在运行的进程，即是否存活
     * Created by cafeting on 2017/2/4.
     *
     * @param context 上下文
     * @param uid     已安装应用的 uid
     * @return true 表示正在运行，false 表示没有运行
     */
    public static boolean isProcessRunning(Context context, int uid) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> runningServiceInfos = am.getRunningServices(200);
        if (runningServiceInfos.size() > 0) {
            for (ActivityManager.RunningServiceInfo appProcess : runningServiceInfos) {
                if (uid == appProcess.uid) {
                    return true;
                }
            }
        }
        return false;
    }
}
